/********************************************************************************
  * @file    consolebrowsertab.cpp
  * @author  Lun Li
  * @version V2.2.0
  * @date    2022.7.8
  * @brief   This file provides all ConsoleBrowserTab functions.
  ******************************************************************************/

#include "consolebrowsertab.h"

ConsoleBrowserTab::ConsoleBrowserTab(ProgramConfig *const config, QWidget *parent):
    QWidget(parent),
    m_config(config)
{
    hintView = new QPlainTextEdit;
    consoleView = new QPlainTextEdit;
    cmdInputLineEdit = new CommandLineEdit;
    cmdFileButton = new QPushButton(tr("File"));

    QWidget *viewWidget = new QWidget;
    viewWidget->setLayout(new NoMarginHBoxLayout);
    viewWidget->layout()->addWidget(hintView);
    viewWidget->layout()->addWidget(consoleView);
    viewWidget->layout()->setSpacing(0);

    QWidget *cmdWidget = new QWidget;
    cmdWidget->setLayout(new NoMarginHBoxLayout);
    cmdWidget->layout()->addWidget(cmdInputLineEdit);
    cmdWidget->layout()->addWidget(cmdFileButton);

    setLayout(new NoMarginVBoxLayout);
    layout()->addWidget(viewWidget);
    layout()->addWidget(cmdWidget);

    hintView->setReadOnly(true);
    hintView->setMaximumWidth(15);
    hintView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    hintView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    hintView->setFont(QFont("宋体", 12));

    consoleView->setReadOnly(true);
    consoleView->setFont(QFont("宋体", 12));
    consoleView->setLineWrapMode(QPlainTextEdit::NoWrap);

    connect(cmdInputLineEdit, &QLineEdit::returnPressed, this, &ConsoleBrowserTab::on_cmdInputReturnPressed);
    connect(cmdFileButton, &QPushButton::clicked, this, &ConsoleBrowserTab::on_cmdFileButtonClicked);
    connect(consoleView->verticalScrollBar(), &QScrollBar::valueChanged, hintView->verticalScrollBar(), &QScrollBar::setValue);
    connect(consoleView, &QPlainTextEdit::textChanged, this, [=]() {
        hintView->horizontalScrollBar()->setVisible(consoleView->horizontalScrollBar()->isVisible());
    });
}

void ConsoleBrowserTab::appendInput(const QString &cmd)
{
    QString appendCmd(cmd);
    while (appendCmd.endsWith('\n') || appendCmd.endsWith('\r')) {
        appendCmd.chop(1);
    }
    consoleView->appendPlainText(appendCmd);
    int lineCount = appendCmd.count('\n') + 1;

    // 输入对应着 '>'
    while (lineCount--) {
        hintView->appendPlainText(">");
    }
    cmdInputLineEdit->addCommand(cmd);
}

void ConsoleBrowserTab::appendOutput(const QString &out)
{
    QString appendCmd(out);
    while (appendCmd.endsWith('\n') || appendCmd.endsWith('\r')) {
        appendCmd.chop(1);
    }
    consoleView->appendPlainText(appendCmd);
    int lineCount = appendCmd.count('\n') + 1;

    // 输出对应着 '-'
    while (lineCount--) {
        hintView->appendPlainText("-");
    }
}

void ConsoleBrowserTab::setUsable(bool usable)
{
    cmdInputLineEdit->setEnabled(usable);
    cmdFileButton->setEnabled(usable);
}

void ConsoleBrowserTab::on_cmdInputReturnPressed()
{
    emit cmdIsInput(cmdInputLineEdit->text());
    cmdInputLineEdit->clear();
}

void ConsoleBrowserTab::on_cmdFileButtonClicked()
{
    QString path = QFileDialog::getOpenFileName(this, tr("Select a File"), m_config->lastOpenPath());
    if (path.isEmpty()) {
        return;
    }
    m_config->setLastOpenPath(path);
    QFile file(path);
    if (!file.open(QFile::ReadOnly)) {
        return;
    }
    QStringList commandList;
    while (true) {
        QByteArray aLine;
        aLine = file.readLine();
        if (aLine.isEmpty())
            break;
        commandList << aLine;
    }
    file.close();
    emit cmdIsInput(commandList.join(""));
}
